"""
MinMax TTS服务
提供文本转语音功能，支持流式和非流式模式
使用统一的HTTP客户端提高性能
"""

import logging
import json
import asyncio
from typing import Optional, Dict, Any, List, AsyncGenerator

from ..core.http_client import get_http_client
from ..core.config import settings

logger = logging.getLogger(__name__)


class MinMaxService:
    """
    MinMax文本转语音服务
    提供高质量的语音合成功能
    """

    def __init__(self):
        self.api_key = settings.minmax_api_key
        self.group_id = settings.minmax_group_id
        self.api_base = settings.get_api_base_url("minmax")

    async def close(self):
        """关闭服务（兼容性方法）"""
        # 新架构中HTTP客户端是全局的，不需要单独关闭
        logger.debug("MinMax服务关闭（HTTP客户端由全局管理）")

    async def text_to_speech_stream(
        self,
        text: str,
        model: str = "speech-01-hd",
        # voice_id: str = "female-tianmei",
        voice_id="",
        speed: float = 1.0,
        vol: float = 1.0,
        pitch: int = 0,
        emotion: Optional[str] = None,
        language_boost: str = "auto",
        timber_weights: Optional[List[Dict[str, Any]]] = None,
        basic_emotions: Optional[Dict[str, float]] = None,
    ) -> AsyncGenerator[Dict[str, Any], None]:
        """
        流式文本转语音
        将文本转换为语音并以流式方式返回

        Args:
            text: 要转换的文本
            model: TTS模型名称
            voice_id: 声音ID
            speed: 语音速度
            vol: 音量
            pitch: 音调
            emotion: 情感
            language_boost: 语言增强
            timber_weights: 音色权重
            basic_emotions: 基础情感

        Yields:
            Dict[str, Any]: 流式音频数据块

        Raises:
            ValueError: 参数验证失败或API调用失败
        """
        # 参数验证
        if not text or not text.strip():
            logger.error(f"TTS请求的text参数为空: '{text}'")
            raise ValueError("文本参数不能为空")

        if not self.api_key or not self.group_id:
            logger.error("MinMax API密钥或组ID未配置")
            raise ValueError("MinMax API密钥或组ID未在环境变量中找到")

        # 使用全局HTTP客户端
        client = get_http_client()

        try:
            headers = {
                "Authorization": f"Bearer {self.api_key}",
                "Content-Type": "application/json",
            }

            # 确保数值类型参数为数值而非字符串
            try:
                speed_value = float(speed) if isinstance(speed, str) else float(speed)
                vol_value = float(vol) if isinstance(vol, str) else float(vol)
                pitch_value = int(pitch) if isinstance(pitch, str) else int(pitch)
            except (ValueError, TypeError) as e:
                logger.error(f"参数类型转换错误: {e}")
                speed_value = 1.0
                vol_value = 1.0
                pitch_value = 0

            # 根据官方示例构建请求参数
            payload = {
                "model": model,
                "text": text,
                "voice_setting": {
                    "voice_id": voice_id,
                    "speed": speed_value,
                    "vol": vol_value,
                    "pitch": pitch_value,
                    "latex_read": False,
                },
                "stream": True,  # 启用流式
                "language_boost": language_boost,
                "audio_setting": {
                    "sample_rate": 32000,
                    "bitrate": 128000,
                    "format": "mp3",
                    "channel": 1,
                },
            }

            # 快速添加可选参数
            if timber_weights:
                payload["timber_weights"] = [
                    {
                        "voice_id": w["voice_id"],
                        "weight": (
                            int(w["weight"])
                            if isinstance(w["weight"], str)
                            else w["weight"]
                        ),
                    }
                    for w in timber_weights
                    if "voice_id" in w and "weight" in w
                ]

            if emotion is not None:
                payload["voice_setting"]["emotion"] = emotion

            # 构建正确的 URL
            url = f"{self.api_base}?GroupId={self.group_id}"

            # 打印即将提交给MinMax API的请求参数
            # logger.info(f"[MinMax] text_to_speech_stream请求参数: URL={url}")
            # logger.info(f"[MinMax] text_to_speech_stream请求头: {json.dumps(headers, ensure_ascii=False, indent=2)}")
            logger.info(
                f"[MinMax] text_to_speech_stream请求体: {json.dumps(payload, ensure_ascii=False, indent=2)}"
            )

            # 先尝试非流式请求以获取完整音频，然后模拟流式发送
            try:
                # 临时改为非流式以获取完整音频数据
                payload["stream"] = False
                response = await client.post(url, headers=headers, json=payload)

                if response.status_code != 200:
                    error_msg = (
                        f"TTS API请求失败: {response.status_code} - {response.text}"
                    )
                    logger.error(error_msg)
                    raise ValueError(error_msg)

                response_data = response.json()

                # 打印MinMax API返回的响应内容
                # logger.info(f"[MinMax] text_to_speech_stream返回内容: {json.dumps(response_data, ensure_ascii=False, indent=2)}")

                # 检查是否有错误响应
                if (
                    "base_resp" in response_data
                    and response_data["base_resp"].get("status_code") != 0
                ):
                    error_info = response_data["base_resp"]
                    error_msg = f"MinMax API错误: status_code={error_info.get('status_code')}, status_msg='{error_info.get('status_msg')}'"
                    logger.error(
                        f"{error_msg}, 完整响应: {json.dumps(response_data, ensure_ascii=False)}"
                    )
                    raise ValueError(
                        f"MinMax API error: {error_info.get('status_msg')} (code: {error_info.get('status_code')})"
                    )

                # 检查音频数据
                if "data" in response_data and "audio" in response_data["data"]:
                    audio_hex = response_data["data"]["audio"]

                    # 将完整音频分块发送以模拟流式
                    chunk_size = 8192  # 每块8KB的十六进制数据
                    total_chunks = (len(audio_hex) + chunk_size - 1) // chunk_size

                    for i in range(total_chunks):
                        start_pos = i * chunk_size
                        end_pos = min((i + 1) * chunk_size, len(audio_hex))
                        chunk = audio_hex[start_pos:end_pos]

                        audio_chunk = {
                            "type": "audio_chunk",
                            "data": {
                                "audio": chunk,
                                "chunk_id": i,
                                "total_chunks": total_chunks,
                            },
                        }
                        yield audio_chunk

                        # 添加小延迟以模拟流式传输
                        await asyncio.sleep(0.1)

                    # 发送完成信号
                    completion_chunk = {
                        "type": "audio_complete",
                        "data": {"status": "completed", "total_chunks": total_chunks},
                    }
                    yield completion_chunk

                else:
                    logger.error(f"音频数据格式不正确: {response_data}")
                    raise ValueError("音频响应格式无效")

            except Exception as e:
                logger.error(f"TTS处理出现意外错误: {str(e)}")
                raise

        except Exception as e:
            logger.error(f"TTS流式处理失败: {str(e)}")
            logger.exception(e)
            raise

    async def text_to_speech(
        self,
        text: str,
        model: str = "speech-01-hd",
        voice_id: str = "female-tianmei",
        speed: float = 1.0,
        vol: float = 1.0,
        pitch: int = 0,
        emotion: Optional[str] = None,
        stream: bool = True,
        language_boost: str = "auto",
        timber_weights: Optional[List[Dict[str, Any]]] = None,
        basic_emotions: Optional[Dict[str, float]] = None,
    ) -> Dict[str, Any]:
        """
        文本转语音（统一接口）
        根据stream参数决定使用流式或非流式模式

        Args:
            text: 要转换的文本
            model: TTS模型名称
            voice_id: 声音ID
            speed: 语音速度
            vol: 音量
            pitch: 音调
            emotion: 情感
            stream: 是否使用流式模式
            language_boost: 语言增强
            timber_weights: 音色权重
            basic_emotions: 基础情感

        Returns:
            Dict[str, Any]: 音频数据
        """
        if stream:
            # 如果是流式，收集所有块并返回完整响应
            audio_chunks = []
            async for chunk in self.text_to_speech_stream(
                text,
                model,
                voice_id,
                speed,
                vol,
                pitch,
                emotion,
                language_boost,
                timber_weights,
                basic_emotions,
            ):
                if chunk["type"] == "audio_chunk":
                    audio_chunks.append(chunk["data"]["audio"])
                elif chunk["type"] == "audio_complete":
                    # 合并所有音频块
                    complete_audio = "".join(audio_chunks)
                    return {"data": {"audio": complete_audio}, "status": "completed"}

            # 如果没有收到完成信号，合并现有块
            if audio_chunks:
                complete_audio = "".join(audio_chunks)
                return {"data": {"audio": complete_audio}, "status": "completed"}
        else:
            # 非流式调用（保持原有逻辑）
            return await self._text_to_speech_non_stream(
                text,
                model,
                voice_id,
                speed,
                vol,
                pitch,
                emotion,
                language_boost,
                timber_weights,
                basic_emotions,
            )

    async def _text_to_speech_non_stream(
        self,
        text: str,
        model: str = "speech-01-hd",
        voice_id: str = "female-tianmei",
        speed: float = 1.0,
        vol: float = 1.0,
        pitch: int = 0,
        emotion: Optional[str] = None,
        language_boost: str = "auto",
        timber_weights: Optional[List[Dict[str, Any]]] = None,
        basic_emotions: Optional[Dict[str, float]] = None,
    ) -> Dict[str, Any]:
        """
        非流式文本转语音
        提供传统的一次性语音生成功能

        Args:
            text: 要转换的文本
            model: TTS模型名称
            voice_id: 声音ID
            speed: 语音速度
            vol: 音量
            pitch: 音调
            emotion: 情感
            language_boost: 语言增强
            timber_weights: 音色权重
            basic_emotions: 基础情感

        Returns:
            Dict[str, Any]: 完整的音频响应数据
        """
        # 参数验证
        if not text or not text.strip():
            logger.error(f"TTS请求的text参数为空: '{text}'")
            raise ValueError("文本参数不能为空")

        if not self.api_key or not self.group_id:
            logger.error("MinMax API密钥或组ID未配置")
            raise ValueError("MinMax API密钥或组ID未在环境变量中找到")

        # 使用全局HTTP客户端
        client = get_http_client()

        try:
            headers = {
                "Authorization": f"Bearer {self.api_key}",
                "Content-Type": "application/json",
            }

            # 确保数值类型参数为数值而非字符串
            try:
                speed_value = float(speed) if isinstance(speed, str) else float(speed)
                vol_value = float(vol) if isinstance(vol, str) else float(vol)
                pitch_value = int(pitch) if isinstance(pitch, str) else int(pitch)
            except (ValueError, TypeError) as e:
                logger.error(f"参数类型转换错误: {e}")
                speed_value = 1.0
                vol_value = 1.0
                pitch_value = 0

            # 根据官方示例构建请求参数
            payload = {
                "model": model,
                "text": text,
                "voice_setting": {
                    "voice_id": voice_id,
                    "speed": speed_value,
                    "vol": vol_value,
                    "pitch": pitch_value,
                    "latex_read": False,
                },
                "stream": False,
                "language_boost": language_boost,
                "audio_setting": {
                    "sample_rate": 32000,
                    "bitrate": 128000,
                    "format": "mp3",
                    "channel": 1,
                },
            }

            # 快速添加可选参数
            if timber_weights:
                payload["timber_weights"] = [
                    {
                        "voice_id": w["voice_id"],
                        "weight": (
                            int(w["weight"])
                            if isinstance(w["weight"], str)
                            else w["weight"]
                        ),
                    }
                    for w in timber_weights
                    if "voice_id" in w and "weight" in w
                ]

            if emotion is not None:
                payload["voice_setting"]["emotion"] = emotion

            # 构建正确的 URL
            url = f"{self.api_base}?GroupId={self.group_id}"

            # 打印即将提交给MinMax API的请求参数（非流式）
            logger.info(f"[MinMax] _text_to_speech_non_stream请求参数: URL={url}")
            logger.info(
                f"[MinMax] _text_to_speech_non_stream请求头: {json.dumps(headers, ensure_ascii=False, indent=2)}"
            )
            logger.info(
                f"[MinMax] _text_to_speech_non_stream请求体: {json.dumps(payload, ensure_ascii=False, indent=2)}"
            )

            response = await client.post(url, headers=headers, json=payload)

            if response.status_code != 200:
                error_msg = f"TTS API请求失败: {response.status_code} - {response.text}"
                logger.error(error_msg)
                raise ValueError(error_msg)

            response_data = response.json()

            # 打印MinMax API返回的响应内容（非流式）
            # logger.info(
            #     f"[MinMax] _text_to_speech_non_stream返回内容: {json.dumps(response_data, ensure_ascii=False, indent=2)}"
            # )

            # 检查是否有错误响应
            if (
                "base_resp" in response_data
                and response_data["base_resp"].get("status_code") != 0
            ):
                error_info = response_data["base_resp"]
                error_msg = f"MinMax API错误: status_code={error_info.get('status_code')}, status_msg='{error_info.get('status_msg')}'"
                logger.error(
                    f"{error_msg}, 完整响应: {json.dumps(response_data, ensure_ascii=False)}"
                )
                raise ValueError(
                    f"MinMax API error: {error_info.get('status_msg')} (code: {error_info.get('status_code')})"
                )

            return response_data

        except Exception as e:
            logger.error(f"非流式TTS处理失败: {str(e)}")
            logger.exception(e)
            raise


# 允许 minmax_service 的 info 日志输出
logging.getLogger("app.services.minmax_service").setLevel(logging.INFO)
